/*
 *  ifxmetadata.hpp - Informix dbExpress metadata classes
 *
 *    Copyright (c) 2001-2006, Luxena Software Company. All rights reserved.
 *
 *  Purpose:
 *
 */

#ifndef __IFXMETADATA_HPP__
#define __IFXMETADATA_HPP__

#ifndef __cplusplus
#error This header requires a C++ compiler ...
#endif

#include <map>
#include "cstr.hpp"
#include "dbxpress.hpp"
#include "dbxcommon.hpp"
#include "ifxconnection.hpp"
#include "ifxcursor.hpp"


/////////////////////////////////////////////////////////////////////////////
// CInformixTablesCursor

class CInformixTablesCursor : public CInformixTrimingCursor
{
public:
	CInformixTablesCursor (CInformixCommand *command);
	SQL_METHOD next ();
private:
	eSQLTableType& _dbxTableType;
	char& _ifxTableType;
};


/////////////////////////////////////////////////////////////////////////////
// CInformixColumnsCursor

class CInformixColumnsCursor : public CInformixTrimingCursor
{
public:
	CInformixColumnsCursor (CInformixCommand *command);
	SQL_METHOD next ();
private:
	INT32& _dbxColumnType;
	INT32& _dbxColumnDataType;
	pCHAR _dbxColumnTypeName;
	INT32& _dbxColumnSubType;
	INT32& _dbxColumnPrecision;
	INT32& _dbxColumnScale;
	int2& _dbxColumnLength;
	INT32& _dbxColumnNullable;
	int2& _ifxColumnType;
	int4& _ifxColumnXID;
	char *_ifxColumnTypeName;
};


/////////////////////////////////////////////////////////////////////////////
// CInformixProcParamsCursor

class CInformixProcParamsCursor : public CInformixTrimingCursor
{
public:
	CInformixProcParamsCursor (CInformixCommand *procParamsCommand);
	SQL_METHOD next ();
private:
	INT32 _recordCounter;
	INT32 _paramCounter;
	// data bound member varibles
	INT32& _dbxRecNo;
	pCHAR _dbxParamName;
	INT32& _dbxPosition;
	int4& _ifxNumArgs;
};


/////////////////////////////////////////////////////////////////////////////
// CInformixIndicesCursor

class CInformixIndicesCursor : public CInformixTrimingCursor
{
public:
	CInformixIndicesCursor (CInformixCommand *indicesCommand, CInformixCommand *columnsCommand, UINT32 indexType);
	SQL_METHOD next ();
private:
	void fetchNextIndex ();
	void fetchNextRecord ();
	void readColumnsOfTables (CInformixCommand *columnsCommand);
	UINT32 _indexTypeFilter;
	typedef std::map<int, _cstr_t> Columns;
	typedef std::map<int, Columns> Tables;
	Tables _tables;
	INT32 _recordCounter;
	INT32 _indexType;
	Columns *_currentTableColumns;
	int _currentIndexPart;
	int2 _currentIndexColumn;
	// data bound member varibles
	INT32& _dbxRecNo;
	pCHAR _dbxIndexName;
	pCHAR _dbxPrimaryKeyName;
	pCHAR _dbxColumnName;
	INT32& _dbxColumnPosition;
	INT32& _dbxIndexType;
	char& _dbxSortOrder;
	int4& _ifxTabID;
	char& _ifxIndexType;
};


/////////////////////////////////////////////////////////////////////////////
// CInformixMetaData - SQLMetaData implementation for Informix

class CInformixMetaData : public CErrorHandlingImpl< CUnknownImpl<SQLMetaData> >,
	private IDatabaseChangeObserver
{
public:
	CInformixMetaData (CInformixConnection *connection);
	virtual ~CInformixMetaData();

	CInformixConnection * getConnection ();

// SQLMetaData
	SQL_METHOD setOption (eSQLMetaDataOption eDOption, INT32 lValue);
	SQL_METHOD getOption (eSQLMetaDataOption eDOption, pINT32 plValue, INT16 iMaxLength, pINT16 piLength);
	SQL_METHOD getObjectList (eSQLObjectType eObjType, ppSQLCursor ppCur);
	SQL_METHOD getTables (pCHAR pszTableName, UINT32 uTableType, ppSQLCursor ppCur);
	SQL_METHOD getProcedures (pCHAR pszProcName, UINT32 uProcType, ppSQLCursor ppCur);
	SQL_METHOD getColumns (pCHAR pszTableName, pCHAR pszColumnName, UINT32 uColType, ppSQLCursor ppCur);
	SQL_METHOD getProcedureParams (pCHAR pszProcName, pCHAR pszParamName, ppSQLCursor ppCur);
	SQL_METHOD getIndices (pCHAR pszTableName, UINT32 uIndexType, ppSQLCursor ppCur);

private:
	static char * checkPattern (char *pszPattern);

	void setResourceDefaults ();
	void freeResources ();

	CInformixCommand * getTablesCommand ();
	CInformixCommand * getProceduresCommand ();
	CInformixCommand * getColumnsCommand ();
	CInformixCommand * getColumnsShortCommand ();
	CInformixCommand * getProcParamsCommand ();
	bool isOnLineIndices ();
	CInformixCommand * getIndicesCommand ();

	CInformixConnection *_connection;
	CInformixCommand *_commandTables;
	CInformixCommand *_commandProcedures;
	CInformixCommand *_commandColumns;
	CInformixCommand *_commandProcParams;
	CInformixCommand *_commandColumnsShort;
	CInformixCommand *_commandIndices;

	                        // dbExpress metadata options
	                        // __________________________
	                        //
	_cstr_t _database;      // eMetaCatalogName
	_cstr_t _user;          // eMetaSchemaName
	                        // eMetaDatabaseName
	                        // eMetaDatabaseVersion
	                        // eMetaTransactionIsoLevel
	                        // eMetaSupportsTransaction
	                        // eMetaMaxObjectNameLength
	                        // eMetaMaxColumnsInTable
	                        // eMetaMaxColumnsInSelect
	                        // eMetaMaxRowSize
	                        // eMetaMaxSQLLength
	                        // eMetaObjectQuoteChar
	                        // eMetaSQLEscapeChar
	                        // eMetaProcSupportsCursor
	                        // eMetaProcSupportsCursors
	                        // eMetaSupportsTransactions
	                        // eMetaPackageName

// IDatabaseChangeObserver
	virtual void databaseChanged ();
};

#endif // __IFXMETADATA_HPP__
